package com.itestor.iptv.global.actions;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.itestor.iptv.global.GlobalConstant;
import com.itestor.iptv.global.bean.AbstractPagedQuery;


/**
 * 实现分页查询的Action抽象类.
 */
public abstract class AbstractPagedQueryAction extends Action {

	/**
	 * 参数名：当前记录数.
	 */
	protected static final String pOffset = "pager.offset";
	/**
	 * 此属性等同于pOffset，用于外部引用
	 */
	public static final String _pOffset = pOffset;

	/**
	 * 参数名：当前记录数.
	 */
	protected static final String sOffset = "pgoffset";

	/**
	 * 参数名：总记录数.
	 */
	protected static final String sCount = "sum";
	/**
	 * 此属性等同于sCount，用于外部引用
	 */
	public static final String _sCount = sCount;

	/**
	 * 参数名：每页记录数.
	 */
	protected static final String sPerPage = "count";

	/**
	 * 参数名：分页超链接数量.
	 */
	protected static final String sPages = "pages";

	/**
	 * 参数名：url地址.
	 */
	protected static final String sUrl = "url";

	/**
	 * 参数名：url参数.
	 */
	protected static final String sParams = "params";

	/**
	 * 参数名：结果集.
	 */
	protected static final String sItems = GlobalConstant.REQUEST_ATTR_PAGER_ITEMS;

	/**
	 * 默认的分页显示时显示的分页超链接数量.
	 */
	protected static final int DEFAULT_INDEXPAGES = 5;

	/**
	 * 默认的forward名称.
	 */
	protected static final String DEFAULT_FORWARD = GlobalConstant.FORWARD_SUCCESS;

	/**
	 * 取得pager标签的INDEX_PAGES的maxIndexPages属性值,即分页显示时显示的分页超链接数量.
	 */
	protected int indexPages = DEFAULT_INDEXPAGES;

	/**
	 * action的forward名称.
	 */
	protected String forwardName = DEFAULT_FORWARD;

	/**
	 * @return the forwardName
	 */
	public String getForwardName() {
		return forwardName;
	}

	/**
	 * @param pForwardName the forwardName to set
	 */
	public void setForwardName(String pForwardName) {
		this.forwardName = pForwardName;
	}

	/**
	 * @return Returns the indexPages.
	 */
	public int getIndexPages() {
		return indexPages;
	}

	/**
	 * @param pIndexPages The indexPages to set.
	 */
	public void setIndexPages(int pIndexPages) {
		this.indexPages = pIndexPages;
	}

	/**
	 * @param form actionForm
	 * @param mapping struts mapping
	 * @param request http request
	 * @param response http response
	 * @return actionForward
	 * @throws Exception any exception
	 */
	@SuppressWarnings("unchecked")
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		// 确定查询第几页
		int pagerOffset = 0;
		if (null != request.getParameter(pOffset)) {
			pagerOffset = Integer.valueOf(request.getParameter(pOffset));
		}

		// 确定是否查询总页数
		int pagerCount = -1;
		if (null != request.getParameter(sCount)) {
			pagerCount = Integer.valueOf(request.getParameter(sCount));
		}

		// 调用doPagedQuery()进行查询
		AbstractPagedQuery pagedQuery = doPagedQuery(form, request, pagerCount, pagerOffset);

		if (pagedQuery == null || pagedQuery.getPagerCount() == -1) {
			return this.getEmptyResultForward(mapping);
		} else {
			request.setAttribute(sOffset, pagerOffset);
			// 查询的记录总数
			request.setAttribute(sCount, pagedQuery.getPagerCount());

			// 每页显示的条数
			request.setAttribute(sPerPage, pagedQuery.getPagerPerPage());

			// 分页显示时显示的分页数量 ，对应<pg:pager>标签的maxIndexPages的值
			request.setAttribute(sPages, getIndexPages());

			// 查询Action的url地址
			request.setAttribute(sUrl, getUrl(request));

			// 查询参数字符串（不包含“?“的符合URL标准的参数名=值的字符串）
			request.setAttribute(sParams, getUrlParams(form, request) + "&" + sCount + "=" + pagedQuery.getPagerCount());

			// 查询结果集放入request中的名字常量
			request.setAttribute(sItems, pagedQuery.getQueryResults());
			
			//_pOffset和_sCount在导出告警EXCEL时需要页面查询值
			request.setAttribute("_pOffset", _pOffset);
			request.setAttribute(_pOffset, pagerOffset);
			request.setAttribute("_sCount", _sCount);
			request.setAttribute(_sCount, pagedQuery.getPagerCount());

			return mapping.findForward(forwardName);
		}
	}

	/**
	 * 当没有查询结果记录时，返回到该页面，默认为返回查询Input界面.
	 * @param mapping action mapping
	 * @return action forward
	 */
	protected ActionForward getEmptyResultForward(ActionMapping mapping) {
		return mapping.getInputForward();
	}

	/**
	 * 从request中提取查询参数并转化为url形式的字符串.
	 * @param form action form
	 * @param request http request
	 * @return url字符串形式的param
	 */
	@SuppressWarnings("unchecked")
	protected String getUrlParams(ActionForm form, HttpServletRequest request) {
		Map reqParamMap = request.getParameterMap();
		return buildQueryString(reqParamMap, new String[] { pOffset, sCount }).toString();
	}

	/**
	 * 返回查询Action的url , 缺省为request.getRequestURI()，不带任何参数.
	 * @param request httpRequest
	 * @return Returns the url.
	 */
	protected String getUrl(final HttpServletRequest request) {
		return request.getRequestURI();
	}

	/**
	 * Builds a query string from a given map of parameters.
	 * @param paramMap A map of parameters
	 * @param excludeParamNames 需要排除的参数
	 * @return query string (with no leading "?")
	 */
	@SuppressWarnings("unchecked")
	protected static StringBuilder buildQueryString(Map paramMap, String[] excludeParamNames) {
		StringBuilder aReturn = new StringBuilder();
		Set aEntryS = paramMap.entrySet();
		Iterator aEntryI = aEntryS.iterator();
		while (aEntryI.hasNext()) {
			Map.Entry aEntry = (Map.Entry) aEntryI.next();
			Object theValue = aEntry.getValue();

			if (theValue != null) {
				String key = (String) aEntry.getKey();
				boolean isExcudeKey = false;
				for (String excludeKey : excludeParamNames) {
					if (key.equalsIgnoreCase(excludeKey)) {
						isExcudeKey = true;
						break;
					}
				}
				if (isExcudeKey) {
					continue;
				}
				if (theValue instanceof String) {
					append(key, (String) theValue, aReturn);
				} else if (theValue instanceof String[]) {
					String[] aValues = (String[]) theValue;

					for (String val : aValues) {
						append(key, val, aReturn);
					}
				} else {
					append(key, theValue.toString(), aReturn);
				}
			}
		}
		return aReturn;
	}

	/**
	 * Appends new key and value pair to query string.
	 * @param key parameter name
	 * @param value value of parameter
	 * @param queryString existing query string
	 * @return query string (with no leading "?")
	 */
	protected static StringBuilder append(String key, String value, StringBuilder queryString) {
		if (queryString.length() >= 0) {
			queryString.append("&");
		}

		try {
			queryString.append(URLEncoder.encode(key, "UTF-8"));
			queryString.append("=");
			queryString.append(URLEncoder.encode(value, "UTF-8"));
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		return queryString;
	}

	/**
	 * 构造(解析）分页查询对象，需要从request中获取查询参数并调用业务服务对象完成分页查询.
	 * @param form action form
	 * @param request http request
	 * @param pagerCount 纪录总条数
	 * @param pagerOffset 查询第几条记录，从0开始
	 * @return AbstractPagedQuery 已经包含有查询结果的PagedQuery对象
	 * @throws Exception any exception
	 */
	@SuppressWarnings("unchecked")
	public abstract AbstractPagedQuery doPagedQuery(ActionForm form, HttpServletRequest request, int pagerCount, int pagerOffset)
			throws Exception;
}
